import XLSX from 'xlsx'
import nodePath from 'node:path'
import { dialog, ipcMain } from 'electron'
import type { IpcMainInvokeEvent, OpenDialogOptions } from 'electron'

/**
 * 导入 Excel
 */
ipcMain.handle(
  'importExcel',
  async (event: IpcMainInvokeEvent, defaultPath: string | undefined) => {
    // 文件存储路径
    const excelFilePath = await selectLocalExcelPath(defaultPath)
    // 未选择任何文件
    if (!excelFilePath) {
      return
    }

    // 解析路径
    const pathResult = nodePath.parse(excelFilePath)
    // 目录名
    const dirName = pathResult.dir
    // 文件名
    const fileName = pathResult.base

    const result: IExcelInitialData = {
      excelFileName: fileName,
      path: dirName,
      fullPath: excelFilePath,
      excelFileContent: []
    }

    // 读取文件
    const workbook = XLSX.readFile(excelFilePath)

    // Excel 至少会包含一个 Sheet
    const sheetNames = workbook.SheetNames
    if (sheetNames.length > 1) {
      event.sender.send('selectExcelSheet', sheetNames, result)
      return
    }

    // 解析 Excel 为数组格式的数据
    const excelFileContent = parseLocalExcelToArr(excelFilePath, sheetNames[0])
    result.excelFileContent = excelFileContent
    return result
  }
)

/**
 * 解析 Excel 为 JSON 格式的数据
 */
ipcMain.handle(
  'parseExcelToJSON',
  (_event: IpcMainInvokeEvent, excelFilePath: string, sheetName: string) => {
    return parseLocalExcelToArr(excelFilePath, sheetName)
  }
)

/**
 * 选择本地 Excel 文件,并返回存储路径
 * @returns 文件的存储路径 / undefined
 */
const selectLocalExcelPath = async (
  defaultPath: string | undefined
): Promise<string | undefined> => {
  const options: OpenDialogOptions = {
    title: '选择Excel',
    filters: [{ name: 'Excel', extensions: ['xls', 'xlsx'] }],
    properties: ['openFile']
  }

  if (defaultPath) {
    options.defaultPath = defaultPath
  }

  const { filePaths } = await dialog.showOpenDialog(options)

  return filePaths[0]
}

/**
 * 根据 Excel 文件存储路径和指定的 Sheet 名称,解析 Excel 文件数据为对象数组
 * @param excelFilePath 文件的存储路径
 * @param sheetName 指定的 Sheet 名称
 */
const parseLocalExcelToArr = (
  excelFilePath: string,
  sheetName: string
): string[][] => {
  // 读取文件
  const workbook = XLSX.readFile(excelFilePath)
  // 读取对应的 Sheet
  const sheet = workbook.Sheets[sheetName]

  // 解析为数组对象
  return XLSX.utils.sheet_to_json<string[]>(sheet, {
    header: 1
  })
}
